package cn.sylinx.horm.util;

import java.util.Arrays;
import java.util.Map;

import cn.sylinx.horm.config.OrmConfigHolder;

/**
 * 缓存键生成器
 * 
 * @author han
 *
 */
public abstract class CacheKeyGenerator {

    private CacheKeyGenerator() {
    }

    /**
     * 默认分隔符
     */
    private static final String KEY_SEP = "|";

    /**
     * 通过参数生成对应的缓存键
     * 
     * @param objects 对象数组
     * @return 键
     */
    public static String generateCacheKey(Object... objects) {

        StringBuilder sb = new StringBuilder();
        String tmp = null;

        for (Object object : objects) {
            tmp = toString(object);
            if (tmp != null) {
                sb.append(tmp).append(KEY_SEP);
            }
        }

        if (sb.length() > 0) {
            sb.delete(sb.length() - KEY_SEP.length(), sb.length());
        }

        String cacheKey = sb.toString();
        return OrmConfigHolder.isCacheKeyMd5() ? MD5Util.md5(cacheKey) : cacheKey;
    }

    /**
     * 对象转字符串
     * 
     * @param object object对象
     * @return 字符串
     */
    private static String toString(Object object) {

        if (object == null) {
            return null;
        }

        // 数组类型
        if (object instanceof Object[]) {

            Object[] tmp = (Object[]) object;
            if (tmp.length < 1) {
                return null;
            }

            StringBuilder sb = new StringBuilder();

            for (Object o : tmp) {

                sb.append(toString(o)).append(KEY_SEP);
            }

            if (sb.length() > 0) {
                sb.delete(sb.length() - KEY_SEP.length(), sb.length());
            }

            return sb.toString();
        }

        // Map类型
        if (object instanceof Map) {

            Map<?, ?> params = (Map<?, ?>) object;
            Object[] objectList = params.keySet().toArray();
            Arrays.sort(objectList);
            StringBuilder sb = new StringBuilder();

            for (Object o : objectList) {

                String key = (String) o;
                Object value = params.get(key);
                sb.append(key).append("=").append(toString(value)).append(KEY_SEP);
            }

            if (sb.length() > 0) {
                sb.delete(sb.length() - KEY_SEP.length(), sb.length());
            }

            return sb.toString();
        }

        return String.valueOf(object);
    }
}
